package com.us.usws.support.uitls;

import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * HttpServletUtils
 *
 * @author Wang Jianbo
 */
public class HttpServletUtils {

	private static Log log = LogFactory.getFactory().getInstance(HttpServletUtils.class);

	/**
	 * Get real IP address from user
	 * @param request
	 * @return
	 */
	public static String getClientIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}

		if (ip.indexOf(',') > 0) {
			ip = ip.substring(0, ip.indexOf(','));
		}
		return ip;
	}

	/**
	 * get request referer
	 * @param request
	 * @return
	 */
	public static String getReferer(HttpServletRequest request) {
		return request.getHeader("Referer");
	}

	/**
	 * debug headers
	 * @param request
	 */
	public static void debugHeaders(HttpServletRequest request) {
		StringBuffer sb = new StringBuffer();
		sb.append("\n............... Debug request start ...............\n");
		//debug headers
		sb.append("<Headers>\n");
		Enumeration<String> e = request.getHeaderNames();
		while (e != null && e.hasMoreElements()) {
			String hName = e.nextElement();
			Enumeration<String> vals = request.getHeaders(hName);
			while (vals.hasMoreElements()) {
				sb.append("\t[").append(hName).append("] ==> [").append(vals.nextElement()).append("]\n");
			}
		}
		sb.append("\n");

		//debug attributes
		sb.append("<Attributes>\n");
		e = request.getAttributeNames();
		while (e != null && e.hasMoreElements()) {
			String aName = e.nextElement();
			Object o = request.getAttribute(aName);
			sb.append("\t[").append(aName).append("] ==> [").append(o).append("]\n");
		}
		sb.append("\n");

		//debug parameters
		sb.append("<Parameters>\n");
		e = request.getParameterNames();
		while (e != null && e.hasMoreElements()) {
			String pName = e.nextElement();
			String[] pVals = request.getParameterValues(pName);
			sb.append("\t[").append(pName).append("] ==> [").append(ArrayUtils.toString(pVals)).append("]\n");
		}
		sb.append("\n");

		//cookies
		sb.append("<Cookies>\n");
		Cookie[] cookies = request.getCookies();
		if (cookies != null && cookies.length > 0) {
			for (Cookie c : cookies) {
				sb.append("\t[").append(c.getName()).append("] = [").append(c.getValue()).append("], ");
				sb.append("[domain/path/secure/maxAge] = [").append(c.getDomain()).append("/").append(c.getPath()).append("/")
						.append(c.getSecure()).append("/").append(c.getMaxAge()).append("]\n");
			}
		}
		sb.append("\n");

		//Locale
		sb.append("<Locale>\n");
		sb.append("\tdefault = [").append(request.getLocale()).append("]\n");
		Enumeration<Locale> locs = request.getLocales();
		if (locs != null) {
			sb.append("\tall = [");
			while (locs.hasMoreElements()) {
				Locale eachLoc = locs.nextElement();
				sb.append(eachLoc.toString()).append("(").append(eachLoc.getDisplayLanguage()).append("/")
						.append(eachLoc.getDisplayCountry()).append("), ");
			}
			sb.deleteCharAt(sb.length() - 1);
			sb.deleteCharAt(sb.length() - 1);
			sb.append("]\n");
		}
		sb.append("\n");

		//server related info
		sb.append("<ServerRelated>\n");

		sb.append("\tgetContextPath() = [").append(request.getContextPath()).append("]\n");
		sb.append("\tgetCharacterEncoding() = [").append(request.getCharacterEncoding()).append("]\n");
		sb.append("\tgetContentLength() = [").append(request.getContentLength()).append("]\n");
		sb.append("\tgetContentType() = [").append(request.getContentType()).append("]\n");
		sb.append("\tgetProtocol() = [").append(request.getProtocol()).append("]\n");
		sb.append("\tgetMethod() = [").append(request.getMethod()).append("]\n");
		sb.append("\n");

		sb.append("\tgetLocalAddr() = [").append(request.getLocalAddr()).append("]\n");
		sb.append("\tgetLocalName() = [").append(request.getLocalName()).append("]\n");
		sb.append("\tgetLocalPort() = [").append(request.getLocalPort()).append("]\n");
		sb.append("\n");

		sb.append("\tgetRemoteAddr() = [").append(request.getRemoteAddr()).append("]\n");
		sb.append("\tgetRemoteHost() = [").append(request.getRemoteHost()).append("]\n");
		sb.append("\tgetRemotePort() = [").append(request.getRemotePort()).append("]\n");
		sb.append("\tgetRemoteUser() = [").append(request.getRemoteUser()).append("]\n");
		sb.append("\n");

		sb.append("\tgetScheme() = [").append(request.getScheme()).append("]\n");
		sb.append("\tisSecure() = [").append(request.isSecure()).append("]\n");
		sb.append("\tgetServerName() = [").append(request.getServerName()).append("]\n");
		sb.append("\tgetServerPort() = [").append(request.getServerPort()).append("]\n");
		sb.append("\tgetServletPath() = [").append(request.getServletPath()).append("]\n");
		sb.append("\tgetQueryString() = [").append(request.getQueryString()).append("]\n");
		sb.append("\n");

		sb.append("\tgetRequestURI() = [").append(request.getRequestURI()).append("]\n");
		sb.append("\tgetRequestURL() = [").append(request.getRequestURL()).append("]\n");
		sb.append("\n");

		sb.append("\tisRequestedSessionIdValid() = [").append(request.isRequestedSessionIdValid()).append("]\n");
		sb.append("\tisRequestedSessionIdFromCookie() = [").append(request.isRequestedSessionIdFromCookie()).append("]\n");
		sb.append("\tisRequestedSessionIdFromURL() = [").append(request.isRequestedSessionIdFromURL()).append("]\n");
		sb.append("\tgetRequestedSessionId() = [").append(request.getRequestedSessionId()).append("]\n");
		sb.append("\n");

		sb.append("\tgetPathInfo() = [").append(request.getPathInfo()).append("]\n");
		sb.append("\tgetPathTranslated() = [").append(request.getPathTranslated()).append("]\n");
		sb.append("\tgetAuthType() = [").append(request.getAuthType()).append("]\n");
		sb.append("\tgetUserPrincipal() = [").append(request.getUserPrincipal()).append("]\n");
		sb.append("\n");

		//end
		sb.append("\n............... Debug request end ...............\n");

		log.trace(sb.toString());
	}

	/**
	 * getServerRequestURL
	 * @param request
	 * @return
	 */
	public static String getServerRequestURL(HttpServletRequest request) {
		StringBuffer sb = new StringBuffer(getHostPath(request));
		sb.append(request.getRequestURI());

		return sb.toString();
	}

	/**
	 * get host path e.g. "http://192.168.0.128:7001"
	 * @return
	 */
	public static String getHostPath(HttpServletRequest request) {
		boolean isSecure = request.isSecure();
		int port = request.getServerPort();

		StringBuffer sb = new StringBuffer();
		if (isSecure) {
			sb.append("https://");
		} else {
			sb.append("http://");
		}

		//get host
		String host = request.getHeader("x-forwarded-host");
		if (host == null || host.length() == 0 || "unknown".equalsIgnoreCase(host)) {
			host = request.getHeader("x-forwarded-server");
		}
		if (host == null || host.length() == 0 || "unknown".equalsIgnoreCase(host)) {
			host = request.getServerName();
			sb.append(host);
			if (port != -1 && ((isSecure && port != 443) || (!isSecure && port != 80))) {
				sb.append(":").append(port);
			}
		} else {
			if (host.indexOf(',') > 0) {
				host = host.substring(0, host.indexOf(','));
			}
			sb.append(host);
		}

		return sb.toString();
	}
}
